7050 // Intel 8250 serial port (UART).
7051 
7052 #include "types.h"
7053 #include "defs.h"
7054 #include "param.h"
7055 #include "traps.h"
7056 #include "spinlock.h"
7057 #include "fs.h"
7058 #include "file.h"
7059 #include "mmu.h"
7060 #include "proc.h"
7061 #include "x86.h"
7062 
7063 #define COM1    0x3f8
7064 
7065 static int uart;    // is there a uart?
7066 
7067 void
7068 uartinit(void)
7069 {
7070   char *p;
7071 
7072   // Turn off the FIFO
7073   outb(COM1+2, 0);
7074 
7075   // 9600 baud, 8 data bits, 1 stop bit, parity off.
7076   outb(COM1+3, 0x80);    // Unlock divisor
7077   outb(COM1+0, 115200/9600);
7078   outb(COM1+1, 0);
7079   outb(COM1+3, 0x03);    // Lock divisor, 8 data bits.
7080   outb(COM1+4, 0);
7081   outb(COM1+1, 0x01);    // Enable receive interrupts.
7082 
7083   // If status is 0xFF, no serial port.
7084   if(inb(COM1+5) == 0xFF)
7085     return;
7086   uart = 1;
7087 
7088   // Acknowledge pre-existing interrupt conditions;
7089   // enable interrupts.
7090   inb(COM1+2);
7091   inb(COM1+0);
7092   picenable(IRQ_COM1);
7093   ioapicenable(IRQ_COM1, 0);
7094 
7095   // Announce that we're here.
7096   for(p="xv6...\n"; *p; p++)
7097     uartputc(*p);
7098 }
7099 
7100 void
7101 uartputc(int c)
7102 {
7103   int i;
7104 
7105   if(!uart)
7106     return;
7107   for(i = 0; i < 128 && !(inb(COM1+5) & 0x20); i++)
7108     microdelay(10);
7109   outb(COM1+0, c);
7110 }
7111 
7112 static int
7113 uartgetc(void)
7114 {
7115   if(!uart)
7116     return -1;
7117   if(!(inb(COM1+5) & 0x01))
7118     return -1;
7119   return inb(COM1+0);
7120 }
7121 
7122 void
7123 uartintr(void)
7124 {
7125   consoleintr(uartgetc);
7126 }
7127 
7128 
7129 
7130 
7131 
7132 
7133 
7134 
7135 
7136 
7137 
7138 
7139 
7140 
7141 
7142 
7143 
7144 
7145 
7146 
7147 
7148 
7149 
